#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@Project ：api_auto_upgrade 
@File    ：yaml_handle.py
@IDE     ：PyCharm 
@Author  ：future76
@Date    ：2024/5/14 9:33 
@Desc    ：yaml文件操作
"""
# 第三方库导入
import yaml
from loguru import logger


class YamlHandle:

    def __init__(self, filename):
        """
        初始化用例文件
        :param filename: 文件绝对路径，如：D:\test\test.yaml
        """
        self.filename = filename
    # TODO 这里有日志输出，之后注意统一优化

    @property
    def read_yaml(self):
        try:
            with open(self.filename, mode="r", encoding="utf-8") as fp:
                return yaml.safe_load(fp.read())
        except FileExistsError as e:
            logger.error(f"YAML file ({self.filename}) not found: {e}")
            raise e
        except yaml.YAMLError as e:
            logger.error(f"Error while reading YAML file ({self.filename}): {e}")
            raise e

    def write(self, data, mode="a"):
        """
        往yaml文件中写入数据，默认是追加写入
        :param data: 要写入的数据,列表或者字典
        :param mode: 写入模式
        :return:
        """
        try:
            with open(self.filename, mode=mode, encoding="utf-8") as f:
                # allow_unicode=True，避免将中文字符转换为 Unicode 转义序列
                yaml.dump(data, f, allow_unicode=True)

        except yaml.YAMLError as e:
            logger.error(f"Error while writing to YAML file ({self.filename}): {e}")
            raise e

    def update(self, key: str, value):
        """
        更改 yaml 文件中的值, 并且保留注释内容
        :param key: 字典的key
        :param value: 写入的值
        :return:
        """
        with open(self.filename, 'r', encoding='utf-8') as file:
            # 创建了一个空列表，里面没有元素
            lines = []
            # 获取yaml文件中的数据
            for line in file.readlines():
                if line != '\n':
                    lines.append(line)

        # TODO 存在a:{b:8155},这种格式的yaml，a还可以修改值或者说是会改成这样a:888{b:8155}，的错误格式问题
        # 写回文件内容，同时更新指定的键
        with open(self.filename, 'w', encoding='utf-8') as file:
            flag = 0    # 标记是否成功更新了指定的键

            for line in lines:
                left_str = line.split(":")[0]
                # 如果这一行全部是注释，保留。不全是进行分割
                if line[0] == '#':
                    right_str = line
                else:
                    right_str = line.split(":", 1)[-1]
                # 如果这一行中不存在任何注释
                if key == left_str.lstrip() and '#' not in line:
                    newline = f"{left_str}: {value}"
                    line = newline
                    file.write(f'{line}\n')
                    flag = 1
                # 如果注释在后面
                elif "#" in line and line[0] != "#":
                    annotation = f'  #{right_str.split("#")[-1]}'
                    newline = f"{left_str}: {value} {annotation}"
                    line = newline
                    file.write(f'{line}\n')
                    flag = 1
                else:
                    file.write(f'{line}')
            return flag


if __name__ == '__main__':
    YamlHandle("test.yaml").update("b", 8155)
    # print(YamlHandle("test.yaml").read_yaml)
